package com.ai.trickycards.ui.activity

import android.animation.ObjectAnimator
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.widget.TextView
import androidx.activity.addCallback
import androidx.annotation.IntRange
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.ai.trickycards.R
import com.ai.trickycards.databinding.ActivityGameBinding
import com.ai.trickycards.entity.enumeration.ActionEnum
import com.ai.trickycards.entity.enumeration.GameMode
import com.ai.trickycards.entity.enumeration.PlayerEnum
import com.ai.trickycards.entity.enumeration.PokerRankEnum
import com.ai.trickycards.ui.dialog.GameOverDialog
import com.ai.trickycards.ui.dialog.GameQuitDialog
import com.ai.trickycards.ui.dialog.RaiseDialog
import com.ai.trickycards.utils.PokerCalculate
import com.ai.trickycards.utils.PokerUtils
import com.ai.trickycards.utils.Utils
import com.ai.trickycards.widgets.ChatView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.math.absoluteValue
import kotlin.random.Random

class GameActivity : BaseActivity() {

    private val binding by lazy {
        ActivityGameBinding.inflate(layoutInflater)
    }

    // ai玩家
    private val playerViews by lazy {
        listOf(
            binding.player01,
            binding.player02,
            binding.player03,
            binding.player04,
            binding.player05
        )
    }

    // 游戏模式
    private val gameMode by lazy {
        intent.getSerializableExtra("gameMode") as GameMode
    }

    // 当前需要做出行动的玩家(规定0表示人类，1表示第一位ai玩家，后面依次类推)
    private var currentPlayerIndex = 0

    // 所有玩家的生命值(规定0表示人类，1表示第一位ai玩家，后面依次类推)
    private val playerLives = mutableListOf<Int>()

    // 当前喊的扑克牌点数
    private var currentRank = PokerRankEnum.Rank2

    // 当前喊的张数
    private var currentCount = 0

    // 当前玩家所做出的决定
    private var actionEnum = ActionEnum.Calzo

    // 游戏开始时间
    private var startGameTime: Long = 0

    /**
     * 是否第一次做出决定（一轮游戏中第一个人第一次做出决定）
     */
    private var isFirstAction = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        setWindowInsets(binding.root)
        binding.ivClose.setOnClickListener {
            GameQuitDialog(this@GameActivity) { finish() }.show()
        }
        onBackPressedDispatcher.addCallback(this, true) { binding.ivClose.callOnClick() }
        binding.tvCalzo.setOnClickListener(::doHumanCalzo)
        binding.tvRaise.setOnClickListener(::doHumanRaise)
        binding.tvDoubt.setOnClickListener(::doHumanDoubt)

        init()
    }

    private fun init() {
        val userInfo = appViewModel.userInfoFlow.value

        // 设置游戏背景
        binding.ivPokerGirl.setImageResource(if (userInfo.gameBg != R.mipmap.background03) R.mipmap.poker_girl1 else R.mipmap.poker_girl2)
        binding.root.setBackgroundResource(userInfo.gameBg)

        // 随机玩家
        val players = PlayerEnum.entries.shuffled()
        // 显示玩家（根据不同游戏模式显示不同个数的玩家）
        playerViews.forEachIndexed { index, playerView ->
            playerView.isVisible = index < gameMode.playerCount - 1
            // 根据玩家数量重置玩家扑克牌的大小
            playerView.resize(gameMode.playerCount - 1)
            // 设置玩家头像和昵称
            playerView.setProfile(players[index])
        }

        // 设置人类扑克牌正面样式
        PokerUtils.reLayer(binding.humanPokerCardComposeFace, true)
        binding.humanPokerCardComposeFace.pokerCardViews.forEach { pokerCard ->
            pokerCard.showType = userInfo.cardFace
        }

        // 设置人类扑克牌背面样式
        PokerUtils.reLayer(binding.humanPokerCardComposeBack, true)
        binding.humanPokerCardComposeBack.pokerCardViews.forEach { pokerCard ->
            pokerCard.showType = userInfo.backStyle
        }

        PokerUtils.rub(this@GameActivity, binding.humanPokerCardComposeFace, binding.humanPokerCardComposeBack)

        // 初始化玩家的生命值
        playerLives.clear()
        repeat(gameMode.playerCount) {
            playerLives.add(gameMode.lives)
        }
        showLives()

        resetGame(false)
    }

    private fun showLives() {
        binding.tvLives.text = "${playerLives[0]}"
        playerViews.take(gameMode.playerCount - 1).forEachIndexed { index, playerView ->
            playerView.setLives(playerLives[index + 1])
        }
    }

    /**
     * @param round 是否从新开始的回合
     */
    private fun resetGame(round: Boolean) {
        binding.chatView.isVisible = false
        // 隐藏对手的扑克牌
        playerViews.take(gameMode.playerCount - 1).map { it.pokerCardCompose }.forEach { pokerCardCompose ->
            pokerCardCompose.isVisible = false
        }
        // 隐藏中间猜测的张数和点数
        binding.tvCount.isVisible = false
        binding.tvRank.isVisible = false
        // 显示中间的13张扑克(显示背面)
        showCenterPokers(false)
        // 隐藏人类的扑克牌
        binding.humanPokerCardComposeBack.isVisible = false
        binding.humanPokerCardComposeFace.isVisible = false
        binding.humanPokerCardComposeFace.isEnabled = true
        binding.humanPokerCardComposeBack.isEnabled = true
        // 设置ai玩家非选中状态
        playerViews.take(gameMode.playerCount - 1).forEach { it.isSelected = false }
        // 设置所有扑克牌不显示阴影
        (playerViews.take(gameMode.playerCount - 1).map { it.pokerCardCompose } + binding.humanPokerCardComposeFace).forEach { pokerCardCompose ->
            pokerCardCompose.pokerCardViews.forEach { it.mask = false }
        }

        fun ready() {
            // 隐藏中间13正扑克牌（背面）
            showCenterPokers(true)

            // 显示：可上滑或点击查看自己底牌，再次点击可回到隐藏状态
            val speakList = mutableListOf<String>()
            if (round) {
                speakList.add("New Round")
                speakList.add("")
            }
            speakList.add("Swipe up or tap to check\nyour card")
            speak(speakList)
            reStart()
        }

        lifecycleScope.launch {
            if (round) {
                delay(1800)
                ready()
            } else {
                // 显示Are you ready对话框
                val speakList = listOf("Are you ready?", "", "Let’s start the game")
                binding.chatView.isVisible = true
                binding.chatView.reset()
                binding.chatView.startSpeak(speakList, startDelay = 500, doOnEndDelay = 100) { chat ->
                    chat.setLeftOption("Start") {
                        // 记录游戏开始时间
                        startGameTime = System.currentTimeMillis()
                        // 累计该模式下总共玩过多少次
                        val userInfo = appViewModel.userInfoFlow.value.copy()
                        when (gameMode) {
                            GameMode.Royal -> userInfo.trickyRoyal++
                            GameMode.Number -> userInfo.trickyNumber++
                            GameMode.Complex -> userInfo.trickyComplex++
                        }
                        appViewModel.changeUserInfo(userInfo)

                        ready()
                    }
                }
            }
        }
    }

    private fun speak(
        speakList: List<String>,
        speed: Long = 30,
        startDelay: Long = 0,
        doOnEndDelay: Long = 0,
        doOnEnd: (suspend CoroutineScope.(ChatView) -> Unit)? = null
    ) {
        binding.chatView.isVisible = true
        binding.chatView.reset()
        binding.chatView.startSpeak(speakList, speed, startDelay, doOnEndDelay, doOnEnd)
    }


    /**
     * 显示中间的13张扑克(显示背面)
     */
    private fun showCenterPokers(hide: Boolean) {
        val pokers = listOf(
            binding.pokerBack01,
            binding.pokerBack02,
            binding.pokerBack03,
            binding.pokerBack04,
            binding.pokerBack05,
            binding.pokerBack06,
            binding.pokerBack07,
            binding.pokerBack08,
            binding.pokerBack09,
            binding.pokerBack10,
            binding.pokerBack11,
            binding.pokerBack12,
            binding.pokerBack13
        )

        if (hide) {
            pokers.forEach { it.isVisible = false }
        } else {
            lifecycleScope.launch {
                pokers.forEach {
                    it.isVisible = true
                    delay(50)
                }
            }
        }
    }

    private fun setActionButtonEnabled(
        v: TextView,
        enabled: Boolean,
    ) {
        v.isEnabled = enabled
        if (enabled) {
            v.setTextColor(getColor(R.color.base_black))
            v.backgroundTintList = null
        } else {
            v.setTextColor(Color.parseColor("#999999"))
            v.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#CCCCCC"))
        }
    }

    private fun showActionButton(show: Boolean) {
        if (show) {
            ObjectAnimator.ofFloat(binding.layerActionButton, "translationY", 300 * displayMetrics.density, 0f).apply {
                doOnStart { binding.layerActionButton.isVisible = true }
                interpolator = DecelerateInterpolator()
                duration = 800
                start()
            }

            if (isFirstAction) {
                setActionButtonEnabled(binding.tvRaise, true)
                setActionButtonEnabled(binding.tvCalzo, false)
                setActionButtonEnabled(binding.tvDoubt, false)
            } else {
                val maxRank = if (gameMode == GameMode.Number) PokerRankEnum.Rank9 else PokerRankEnum.RankA
                val maxCount = gameMode.playerCount * if (currentRank == PokerRankEnum.Joker) 1 else 4
                setActionButtonEnabled(binding.tvRaise, currentRank.num < maxRank.num || currentCount < maxCount)
                setActionButtonEnabled(binding.tvCalzo, true)
                setActionButtonEnabled(binding.tvDoubt, true)
            }

        } else {
            binding.layerActionButton.isVisible = false
        }
    }

    /**
     * 摊牌：翻开所有玩家的牌查看结果
     */
    private fun showdown() {
        val userInfo = appViewModel.userInfoFlow.value
        // 翻开ai的扑克牌
        playerViews.take(gameMode.playerCount - 1).map { it.pokerCardCompose }.forEach { pokerCardCompose ->
            pokerCardCompose.pokerCardViews.forEach { pokerCard ->
                pokerCard.showType = userInfo.cardFace
            }
            // 重新叠放扑克牌
            PokerUtils.reLayer(pokerCardCompose, false)
        }

        // 翻开人类的扑克牌
        PokerUtils.flipPoker(binding.humanPokerCardComposeFace, binding.humanPokerCardComposeBack, true)
        binding.humanPokerCardComposeFace.isEnabled = false
        binding.humanPokerCardComposeBack.isEnabled = false

        // 显示遮罩
        (playerViews.take(gameMode.playerCount - 1).map { it.pokerCardCompose } + binding.humanPokerCardComposeFace).forEach { pokerCardCompose ->
            pokerCardCompose.pokerCardViews.forEach { pokerCardView ->
                if (pokerCardView.rank != PokerRankEnum.Joker) {
                    pokerCardView.mask = pokerCardView.rank != currentRank
                }
            }
        }

        calculateResult()
    }

    private fun getPrePlayerIndex() = Utils.getPrePosition(currentPlayerIndex, gameMode.playerCount)

    /**
     * 当在我的决定胜利的时候，会有动效
     */
    private fun showWinAnim() {
        ObjectAnimator.ofFloat(binding.ivFlower, "translationY", 0f, displayMetrics.heightPixels.toFloat()).apply {
            doOnStart { binding.ivFlower.isVisible = true }
            doOnEnd { binding.ivFlower.isVisible = false }
            interpolator = AccelerateInterpolator()
            startDelay = 50
            duration = 1500
            start()
        }
    }

    /**
     * 摊牌后最后的计算结果
     * Calza认可：刚好所有玩家的牌数量等于当前牌桌上的数量，提出Calza的玩家胜利，赢得2生命值
     * Doubt怀疑：猜测牌型相同的卡牌总数小于桌面的猜测的数量时，提出质疑的玩家胜利，增加1生命值，上一位玩家减少1生命值。反之失败。
     *
     * 生命值逻辑：
     * 【Calza】：
     * 正确：提出Calza的生命值+2，其它玩家生命值不变
     * 错误：提出Calza的生命值-2，其它玩家生命值不变
     *
     * 【Doubt】：
     * 正确：提出Doubt的生命值+1，上一玩家生命值-1
     * 错误：提出Doubt的生命值-1，上一玩家生命值+1
     *
     * 积分与等级逻辑：(某个玩家的生命值等于0时表示得出游戏的胜负)
     * 输赢与自己无关：积分+200，等级+2
     * 输了：积分+0，等级+1
     * 赢了：积分+300，等级+4
     */
    private fun calculateResult() = lifecycleScope.launch {
        delay(2000)
        val pokerCount = getPokerCount(currentRank)
        var isRight = false // 是否猜对
        var currentPlayerChangeLives = 0 // 当前玩家需要增加或减少的生命值
        var prePlayerChangeLives = 0 // 前一个玩家需要增加或减少的生命值
        if (actionEnum == ActionEnum.Calzo) {
            // 认可
            isRight = pokerCount == currentCount
            if (isRight) {
                // 提出Calza的生命值+2
                currentPlayerChangeLives = 2
            } else {
                // 提出Calza的生命值-2
                currentPlayerChangeLives = -2
            }
        } else if (actionEnum == ActionEnum.Doubt) {
            // 质疑
            isRight = pokerCount < currentCount
            if (isRight) {
                // 提出Calza的生命值+1，上一玩家生命值-1
                currentPlayerChangeLives = 1
                prePlayerChangeLives = -1
            } else {
                // 提出Calza的生命值-1，上一玩家生命值+1
                currentPlayerChangeLives = -1
                prePlayerChangeLives = 1
            }
        }
        playerLives[currentPlayerIndex] += currentPlayerChangeLives
        playerLives[getPrePlayerIndex()] += prePlayerChangeLives
        // 生命值为负数的情况，将生命值设置为0
        playerLives.forEachIndexed { index, lives ->
            if (lives < 0) {
                playerLives[index] = 0
            }
        }

        if (isRight && currentPlayerIndex == 0) {
            // 当在我的决定胜利的时候，会有动效
            showWinAnim()
        }

        val speakList = if (isRight) {
            listOf("Total:\n${Utils.numToWord(pokerCount)} ${currentRank.fullText}", "", "${actionEnum.name} success")
        } else {
            listOf("Total:\n${Utils.numToWord(pokerCount)} ${currentRank.fullText}", "", "${actionEnum.name} failure")
        }
        speak(speakList, doOnEndDelay = 1500) {
            binding.chatView.isVisible = false
            delay(200)

            val speakList2 = mutableListOf<String>()
            if (currentPlayerChangeLives != 0) {
                if (currentPlayerChangeLives > 0) {
                    speakList2.add("Player $currentPlayerIndex:\nAdd ${Utils.numToWord(currentPlayerChangeLives.absoluteValue).lowercase()} more life")
                } else {
                    speakList2.add("Player $currentPlayerIndex:\nReduce ${Utils.numToWord(currentPlayerChangeLives.absoluteValue).lowercase()} life")
                }
            }
            if (prePlayerChangeLives != 0) {
                if (speakList2.isNotEmpty()) {
                    speakList2.add("")
                }
                if (prePlayerChangeLives > 0) {
                    speakList2.add("Player ${getPrePlayerIndex()}:\nAdd ${Utils.numToWord(prePlayerChangeLives.absoluteValue)} more life")
                } else {
                    speakList2.add("Player ${getPrePlayerIndex()}:\nReduce ${Utils.numToWord(prePlayerChangeLives.absoluteValue)} life")
                }
            }
            if (currentPlayerChangeLives != 0 && prePlayerChangeLives != 0 && currentPlayerChangeLives < 0) {
                speakList2.reverse()
            }
            speakList2.forEachIndexed { index, text ->
                speakList2[index] = text.replace("Player 0", "You")
            }

            showLives()
            speak(speakList2, doOnEndDelay = 2000) {
                if (playerLives.any { it == 0 }) { // 有玩家的生命值为0（已区分出胜负：生命值最大的获胜，为0的失败）
                    val maxLives = playerLives.max()
                    var maxLivesPlayerIndex = 0 // 最大生命值玩家的索引
                    var zeroLivesPlayerIndex = 0 // 最小生命值玩家的索引
                    playerLives.forEachIndexed { index, lives ->
                        if (lives == maxLives && playerLives[maxLivesPlayerIndex] != maxLives) {
                            maxLivesPlayerIndex = index
                        }
                        if (lives == 0) {
                            zeroLivesPlayerIndex = index
                        }
                    }


                    val rewardScore: Int
                    val rewardLevel: Int
                    if (maxLivesPlayerIndex != 0 && zeroLivesPlayerIndex != 0) {
                        // 输赢与自己无关：积分+200，等级+2
                        rewardScore = 200
                        rewardLevel = 2
                    } else if (maxLivesPlayerIndex == 0) {
                        // 赢了：积分+300，等级+4
                        rewardScore = 300
                        rewardLevel = 4
                    } else {
                        // 输了：积分+0，等级+1
                        rewardScore = 0
                        rewardLevel = 1
                    }

                    val userInfo = appViewModel.userInfoFlow.value.copy()
                    if (isRight && currentPlayerIndex == 0) {
                        // 累计胜利次数
                        userInfo.gamesWon++
                    }

                    GameOverDialog(
                        context = this@GameActivity,
                        gameMode = gameMode,
                        winnerIndex = maxLivesPlayerIndex,
                        loserIndex = zeroLivesPlayerIndex,
                        rewardScore = rewardScore,
                        beforeLevel = userInfo.level,
                        newLevel = userInfo.level + rewardLevel
                    ) {
                        userInfo.score += rewardScore
                        userInfo.level += rewardLevel
                        appViewModel.changeUserInfo(userInfo)
                        // 游戏结束，退出Game页面
                        finish()

                    }.show()
                } else {
                    // 所有玩家都还有生命值，游戏继续
                    resetGame(true)
                }
            }
        }
    }

    private fun doHumanAction(
        speakList: List<String>,
        showdown: Boolean
    ) {
        if (showdown) {
            showActionButton(false)
        }
        speak(speakList, startDelay = 200) {
            if (showdown) {
                showdown()
            }
        }
    }

    // 完全认可
    private fun doHumanCalzo(v: View) {
        doHumanAction(listOf("You:\nCalzo!"), true)
        actionEnum = ActionEnum.Calzo
        isFirstAction = false
    }

    // 继续加码
    private fun doHumanRaise(v: View) {
        doHumanAction(listOf("You:\nRaise!"), false)
        actionEnum = ActionEnum.Raise
        RaiseDialog(this, gameMode, isFirstAction, currentCount, currentRank) { count, rank ->
            isFirstAction = false
            showActionButton(false)
            currentCount = count
            currentRank = rank
            lifecycleScope.launch {
                binding.tvCount.text = "$currentCount"
                binding.tvRank.text = currentRank.text
                speak(listOf("Your:\n${Utils.numToWord(currentCount)} ${currentRank.fullText}"))
                delay(1500)
                moveNextPlayer()
                aiLogic()
            }

        }.show()
    }

    // 提出质疑
    private fun doHumanDoubt(v: View) {
        doHumanAction(listOf("You:\nDoubt!"), true)
        actionEnum = ActionEnum.Doubt
        isFirstAction = false
    }

    /**
     * 重新开始游戏
     */
    private fun reStart() {
        // 显示中间的猜测的张数和点数
        binding.tvCount.isVisible = true
        binding.tvRank.isVisible = true
        binding.tvCount.text = ""
        binding.tvRank.text = ""
        // 显示人类扑克牌背面
        binding.humanPokerCardComposeBack.isVisible = true
        binding.humanPokerCardComposeFace.isVisible = true
        PokerUtils.flipPoker(binding.humanPokerCardComposeFace, binding.humanPokerCardComposeBack, false)

        // 显示玩家扑克牌背面
        val userInfo = appViewModel.userInfoFlow.value
        playerViews.take(gameMode.playerCount - 1).map { it.pokerCardCompose }.forEach { pokerCardCompose ->
            pokerCardCompose.isVisible = true
            pokerCardCompose.pokerCardViews.forEach { pokerCard ->
                pokerCard.showType = userInfo.backStyle
            }
            // 重新叠放扑克牌
            PokerUtils.reLayer(pokerCardCompose, true)
        }


        // 默认喊的张数和点数
        currentCount = gameMode.leastPoker
        currentRank = if (gameMode == GameMode.Royal) PokerRankEnum.RankT else PokerRankEnum.Rank2

        // 随机第一位喊牌的玩家
        currentPlayerIndex = Random.nextInt(gameMode.playerCount)
        //currentPlayerIndex = 0

        // 给每个玩家都从一副完整的扑克牌中抽取5张扑克牌
        (playerViews.take(gameMode.playerCount - 1).map { it.pokerCardCompose } + binding.humanPokerCardComposeFace).forEach { pokerCardCompose ->
            val pokers = when (gameMode) {
                GameMode.Number -> {
                    PokerCalculate.numberCards().shuffled().take(5)
                }

                GameMode.Royal -> {
                    PokerCalculate.royalCards().shuffled().take(5)
                }

                else -> {
                    PokerCalculate.complexCard().shuffled().take(5)
                }
            }
            pokerCardCompose.pokerCardViews.forEachIndexed { index, pokerCardView ->
                pokerCardView.rank = pokers[index].rank
                pokerCardView.suit = pokers[index].suit
                pokerCardView.mask = false
            }
        }

        lifecycleScope.launch {
            delay(5000)
            isFirstAction = true
            aiLogic()
        }
    }

    private fun moveNextPlayer() {
        currentPlayerIndex = Utils.getNextPosition(currentPlayerIndex, gameMode.playerCount)
    }

    /**
     * 概率问题：例如要随机30%的可能性，参数就传30
     * @param possibility 可能性
     * @return 概率结果，true表示命中概率，false没有命中概率
     */
    private fun probability(@IntRange(0, 100) possibility: Int): Boolean {
        return Random.nextInt(100) <= possibility
    }

    private suspend fun aiLogic() {
        // 需要做出决定的ai
        val aiIndex = currentPlayerIndex - 1

        // 设置ai玩家是否选中
        playerViews.take(gameMode.playerCount - 1).forEachIndexed { index, playerView ->
            playerView.isSelected = index == aiIndex
        }

        if (currentPlayerIndex == 0) {
            // 需要人类做出决定
            speak(listOf("Your turn"))
            delay(500)
            showActionButton(true)
            return
        }

        // 随机AI思考时间
        delay(Random.nextLong(500, 1500))

        if (isFirstAction) {
            isFirstAction = false
            // 首次发言，可以直接喊花牌（10%的概率直接喊花牌）
            val countJoker = getPokerCount(PokerRankEnum.Joker)
            var rank = if (countJoker >= currentCount) {
                // 30%概率直接喊花牌
                if (probability(30)) PokerRankEnum.Joker else currentRank
            } else {
                // 10%的概率直接喊花牌
                if (probability(10)) PokerRankEnum.Joker else currentRank
            }
            // 如果首次喊的不是花牌
            if (rank != PokerRankEnum.Joker) {
                // 50%的概率点数+1
                if (probability(50)) {
                    rank = PokerRankEnum.valueOfNum(rank.num + 1)
                }

                // 10%的概率张数+1
                if (probability(10)) {
                    currentCount++
                }
            } else {
                currentCount = gameMode.leastJoker
            }
            currentRank = rank
            actionEnum = ActionEnum.Raise
            showCurrent()
            return
        }

        // 非首次发言：
        // 如果前面喊的是花牌，只能在花牌的基础上数量+1。
        if (currentRank == PokerRankEnum.Joker) {
            // 花牌的张数已经达到上限（只能认可或怀疑）
            if (currentCount >= gameMode.playerCount) {
                // 认可和怀疑各占50%的概率
                if (probability(50)) {
                    aiCalzo()
                } else {
                    aiDoubt()
                }
            } else {
                // 花牌张数未达到上下，可以认可、怀疑、随着
                if (probability(10)) {
                    aiCalzo()
                } else if (probability(10)) {
                    aiDoubt()
                } else {
                    currentCount++
                    actionEnum = ActionEnum.Raise
                    showCurrent()
                }
            }
            return
        }

        // 前面喊的不是花牌，可以在点数或数量上+1,也可以怀疑或认可
        val maxRank = if (gameMode == GameMode.Number) PokerRankEnum.Rank9 else PokerRankEnum.RankA
        val maxCount = gameMode.playerCount * if (currentRank == PokerRankEnum.Joker) 1 else 4

        if (probability(10)) {
            aiCalzo()
        } else if (probability(10)) {
            aiDoubt()
        } else if (currentRank.num >= maxRank.num && currentCount >= maxCount) {
            // 张数和点数都已经达到上限，只能怀疑或认可
            if (probability(50)) {
                aiCalzo()
            } else {
                aiDoubt()
            }
        } else if (currentRank.num < maxRank.num && currentCount < maxCount) {
            // 张数和点数都未达到上限
            if (probability(50)) {
                // 张数+1
                currentCount++
            } else {
                // 点数+1
                currentRank = PokerRankEnum.valueOfNum(currentRank.num + 1)
            }
            actionEnum = ActionEnum.Raise
            showCurrent()
        } else if (currentRank.num >= maxRank.num) {
            // 点数达到上下(只能张数+1)
            currentCount++
            actionEnum = ActionEnum.Raise
            showCurrent()
        } else {
            // 张数达到上下，可以点数+1张数恢复最低起喊张数
            currentCount = gameMode.leastPoker
            currentRank = PokerRankEnum.valueOfNum(currentRank.num + 1)
            actionEnum = ActionEnum.Raise
            showCurrent()
        }
    }

    /**
     * ai认可前一个玩家
     */
    private fun aiCalzo() {
        actionEnum = ActionEnum.Calzo
        speak(listOf("Players $currentPlayerIndex\nCalzo!")) {
            showdown()
        }

    }

    /**
     * ai怀疑前一个玩家
     */
    private fun aiDoubt() {
        actionEnum = ActionEnum.Doubt
        speak(listOf("Players $currentPlayerIndex\nDoubt!")) {
            showdown()
        }
    }

    private suspend fun showCurrent(moveToNext: Boolean = true) {
        binding.tvCount.text = "$currentCount"
        binding.tvRank.text = currentRank.text
        speak(listOf("Players $currentPlayerIndex:\n${Utils.numToWord(currentCount)} ${currentRank.fullText}"))
        if (moveToNext) {
            delay(3000)
            moveNextPlayer()
            aiLogic()
        }
    }

    /**
     * 获取桌面上所有玩家指定扑克牌点数的张数总和
     */
    private fun getPokerCount(rank: PokerRankEnum): Int {
        val pokerCardViews = playerViews.take(gameMode.playerCount - 1).map { it.pokerCardCompose.pokerCardViews }.flatten() + binding.humanPokerCardComposeFace.pokerCardViews
        val count = pokerCardViews.count { it.rank == rank }
        if (rank == PokerRankEnum.Joker) {
            return count
        }
        val countJoker = pokerCardViews.count { it.rank == PokerRankEnum.Joker }
        return count + countJoker
    }

    override fun onDestroy() {
        super.onDestroy()
        if (startGameTime > 0) {
            // 累计总过玩了多少时间
            val userInfo = appViewModel.userInfoFlow.value.copy()
            userInfo.timePlayed += System.currentTimeMillis() - startGameTime
            appViewModel.changeUserInfo(userInfo)
        }
    }
}